# Copyright (c) 2024 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

"""符号注册表"""

from typing import Dict, List, Optional
from dataclasses import dataclass, field
from .symbol_meta import Signature, TypeInfo, Symbol, SymbolKind, TypeKind
from mcpy.symbol_meta import TypeInfo, build_type_signature


@dataclass
class TypeScope:
    """类型的符号作用域

    每个类型（如 dict, list, str）都有自己的符号作用域，
    包含该类型的实例方法、类方法和属性。

    对于模板类型（如 tuple[T, Args...]），可以关联到模板类型符号，
    以获取模板参数信息（是否可变参数等）。
    """

    type_name: str
    # 实例方法：需要实例才能调用 (obj.method)
    instance_methods: Dict[str, List[Signature]] = field(default_factory=dict)
    # 类方法/静态方法：通过类名调用 (Class.method)
    class_methods: Dict[str, List[Signature]] = field(default_factory=dict)
    # 属性（暂未使用，为未来扩展预留）
    properties: Dict[str, Symbol] = field(default_factory=dict)
    # 关联的模板类型符号（如果是模板类型）
    template_symbol: Optional["Symbol"] = None


class SymbolRegistry:
    """符号注册表

    支持类型符号和函数符号的统一存储与上下文感知查找
    采用类似 C++ 的模板和特化机制
    """

    def __init__(self):
        # 全局函数：name -> Symbol
        self._functions: Dict[str, Symbol] = {}

        # 全局类型：type_name -> Symbol
        self._types: Dict[str, Symbol] = {}

        # 类型作用域：type_name -> TypeScope
        # 每个类型有自己的方法命名空间，避免冲突
        self._type_scopes: Dict[str, TypeScope] = {}

        # === 类型系统 ===

        # 基础类型: int, str, bool
        self._primitive_types: Dict[str, Symbol] = {}

        # 模板类型: list<T>, dict<K,V>, tuple<Args...>
        self._template_types: Dict[str, Symbol] = {}

        # 类型别名: List -> list, Tuple -> tuple
        self._type_aliases: Dict[str, str] = {}

        # 实例化缓存: "list[int]" -> Symbol
        self._instantiated_types: Dict[str, Symbol] = {}

    def register_type_symbol(
        self, symbol: Symbol, type_config: Optional[Dict] = None
    ) -> None:
        """注册类型符号"""
        # 设置类型配置
        if type_config:
            symbol.type_config = type_config

        # 如果是类，可能需要构造函数签名
        if symbol.kind == SymbolKind.CLASS:
            # 从 symbol 中提取构造函数签名
            signature = symbol.to_signature()
            if signature:
                symbol.add_signature(signature)

        # 注册到全局类型
        self._types[symbol.name] = symbol

    def register_primitive_type(self, name: str, cpp_type: str, **config) -> Symbol:
        """注册基础类型"""
        from mcpy.symbol_meta import TypeInfo, TypeKind

        # 特殊处理：any/Any 类型应该使用 TypeKind.ANY
        if name.lower() == "any":
            type_info = TypeInfo.any()
        else:
            type_info = TypeInfo(
                kind=TypeKind.PRIMITIVE,
                name=name,
                pass_by=config.get("pass_by"),  # 从配置中获取参数传递策略
            )

        # 处理继承关系：填充 base_types
        inherit_from = config.get("inherit_from")
        if inherit_from:
            # 查找基类型的 TypeInfo
            base_symbol = self._primitive_types.get(inherit_from) or self._types.get(
                inherit_from
            )
            if base_symbol and base_symbol.type_info:
                type_info.base_types = [base_symbol.type_info]

        type_config = {"cpp_type": cpp_type, **config}
        symbol = Symbol(
            name=name,
            kind=SymbolKind.CLASS,
            type_info=type_info,
            type_config=type_config,
        )

        # 注册构造函数签名
        self._register_constructors(symbol, type_config)

        # 注册到基础类型表和全局类型表
        self._primitive_types[name] = symbol
        self._types[name] = symbol  # 确保在全局类型表中可查找
        return symbol

    def register_template_type(
        self,
        name: str,
        template_params: List[str],
        cpp_template: str,
        is_variadic: bool = False,
        **config,
    ) -> Symbol:
        """注册模板类型"""
        from mcpy.symbol_meta import TypeInfo, TypeKind

        type_info = TypeInfo(
            kind=TypeKind.GENERIC,
            name=name,
            is_template=True,
            template_params=template_params,
            is_variadic_template=is_variadic,
            min_template_args=len(template_params) if not is_variadic else 1,
            max_template_args=len(template_params) if not is_variadic else None,
            pass_by=config.get("pass_by"),  # 从配置中获取参数传递策略
        )
        type_config = {"cpp_type": cpp_template, **config}
        symbol = Symbol(
            name=name,
            kind=SymbolKind.CLASS,
            type_info=type_info,
            is_template_type=True,
            type_config=type_config,
        )

        # 注册构造函数签名
        self._register_constructors(symbol, type_config)

        # 注册到模板类型表和全局类型表
        self._template_types[name] = symbol
        self._types[name] = symbol  # 确保在全局类型表中可查找
        return symbol

    def _register_constructors(self, symbol: Symbol, type_config: dict) -> None:
        """从类型配置中注册构造函数签名

        Args:
            symbol: 类型符号
            type_config: 类型配置字典
        """
        # 检查是否配置了继承
        inherit_from = type_config.get("inherit_from")
        if inherit_from:
            # 继承场景：从父类型获取构造函数并进行类型替换
            self._inherit_constructors_from_parent(symbol, inherit_from, type_config)
            return

        # 获取构造函数配置
        constructors_config = type_config.get("constructors")
        if not constructors_config:
            return

        # 解析构造函数签名（使用与 methods 相同的格式）
        signatures = constructors_config.get("signatures", [])
        templates = constructors_config.get("templates", [])
        includes = constructors_config.get("includes", [])
        priority = constructors_config.get("priority", 1)

        # 确保 signatures 和 templates 数量匹配
        if len(signatures) != len(templates):
            return

        # 为每个构造函数创建签名对象
        from mcpy.builtin.builtin_table import _parse_signature_string

        for i, sig_str in enumerate(signatures):
            template_str = templates[i] if i < len(templates) else ""
            try:
                # 构建临时配置用于解析
                temp_config = {
                    "includes": includes,
                    "priority": priority,
                }

                # 如果类型有模板参数，传递给签名解析器
                # 这样解析器就知道哪些是模板参数
                if symbol.type_info and symbol.type_info.template_params:
                    temp_config["template_params"] = symbol.type_info.template_params

                # 传递类型的 type_vars 配置
                if type_config and "type_vars" in type_config:
                    temp_config["type_vars"] = type_config["type_vars"]

                # 解析签名（构造函数名就是类型名）
                sig = _parse_signature_string(
                    symbol.name, sig_str, temp_config, template_str
                )
                if sig:
                    # 添加到符号的签名列表
                    symbol.add_signature(sig)
            except Exception:
                # 解析失败时静默跳过
                continue

    def _inherit_constructors_from_parent(
        self, symbol: Symbol, parent_name: str, type_config: dict
    ) -> None:
        """从父类型继承构造函数签名

        Args:
            symbol: 当前类型符号
            parent_name: 父类型名称（如 "list[T]"）
            type_config: 当前类型配置（包含 type_substitution）
        """
        # 从父类型名称中提取基础名称
        base_parent_name = (
            parent_name.split("[")[0] if "[" in parent_name else parent_name
        )

        # 查找父类型符号
        parent_symbol = self._template_types.get(base_parent_name)
        if not parent_symbol or not parent_symbol.signatures:
            return

        # 获取类型替换映射（如 {"T": "mc::variant"}）
        type_substitution = type_config.get("type_substitution", {})

        # 复制父类型的每个签名并进行类型替换
        for parent_sig in parent_symbol.signatures:
            # 创建新的签名对象，进行类型替换
            new_sig = self._apply_type_substitution_to_signature(
                parent_sig, type_substitution, symbol.name
            )
            if new_sig:
                symbol.add_signature(new_sig)

    def _apply_type_substitution_to_signature(
        self, signature: Signature, type_substitution: dict, new_function_name: str
    ) -> Signature:
        """对签名应用类型替换

        Args:
            signature: 原始签名
            type_substitution: 类型替换映射（如 {"T": "mc::variant"}）
            new_function_name: 新的函数名（继承类的名称）

        Returns:
            应用类型替换后的新签名

        注意：如果签名有自己的模板参数（template_params），则不进行类型替换，
        因为签名的模板参数是独立的，不应被继承类的类型替换影响。
        例如：list[T] 的构造函数 list(iterable: set[T]) -> list[T] 中的 T 是签名自己的模板参数。
        """
        # 如果签名有模板参数，说明是通用签名，不进行类型替换
        if signature.template_params:
            # 只替换函数名，保持签名的其他部分不变
            return Signature(
                function_name=new_function_name,
                param_types=signature.param_types,
                return_type=signature.return_type,
                template_params=signature.template_params,
                emit_template=signature.emit_template,
                includes=signature.includes,
                priority=signature.priority,
                args=signature.args,
                optional_params=signature.optional_params,
                is_method=signature.is_method,
                is_mutating=signature.is_mutating,
                is_classmethod=signature.is_classmethod,
                template_param_mapping=signature.template_param_mapping,
                param_defaults=signature.param_defaults,
                optional_fragments=signature.optional_fragments,
                callback_path=signature.callback_path,
                param_overrides=signature.param_overrides,
                type_vars=signature.type_vars,
            )

        # 否则进行类型替换
        # 替换返回类型
        new_return_type = signature.return_type
        for old_type, new_type in type_substitution.items():
            new_return_type = new_return_type.replace(old_type, new_type)

        # 替换参数类型
        new_param_types = []
        for param_type in signature.param_types:
            new_param_type = param_type
            for old_type, new_type in type_substitution.items():
                new_param_type = new_param_type.replace(old_type, new_type)
            new_param_types.append(new_param_type)

        # 替换模板
        new_emit_template = signature.emit_template
        for old_type, new_type in type_substitution.items():
            new_emit_template = new_emit_template.replace(old_type, new_type)

        # 创建新的签名对象
        return Signature(
            function_name=new_function_name,
            param_types=new_param_types,
            return_type=new_return_type,
            template_params=signature.template_params,
            emit_template=new_emit_template,
            includes=signature.includes,
            priority=signature.priority,
            args=signature.args,
            optional_params=signature.optional_params,
            is_method=signature.is_method,
            is_mutating=signature.is_mutating,
            is_classmethod=signature.is_classmethod,
            template_param_mapping=signature.template_param_mapping,
            param_defaults=signature.param_defaults,
            optional_fragments=signature.optional_fragments,
            callback_path=signature.callback_path,
            param_overrides=signature.param_overrides,
            type_vars=signature.type_vars,
        )

    def register_type_alias_new(self, alias: str, canonical: str) -> None:
        """注册类型别名"""
        self._type_aliases[alias] = canonical

    def register_function_symbol(self, symbol: Symbol) -> None:
        """注册函数符号（公共接口）

        Args:
            symbol: 要注册的函数符号
        """
        if symbol.name not in self._functions:
            self._functions[symbol.name] = symbol
        else:
            # 如果已存在，合并签名
            existing = self._functions[symbol.name]
            for sig in symbol.signatures:
                existing.add_signature(sig)

    def register_signature(self, signature: Signature) -> None:
        """注册函数签名或方法签名

        使用新系统的分层索引，避免符号冲突
        """
        func_name = signature.function_name

        # 检查是否为方法签名
        if signature.is_method:
            # 对于方法，第一个参数类型就是类型名（如 "list[T]" 或 "dict"）
            if signature.param_types:
                class_name = signature.param_types[0]

                # 提取基础类型名作为 TypeScope 的 key
                # 所有模板类型的方法都注册到基础类型的 TypeScope 中
                base_type_name = (
                    class_name.split("[")[0] if "[" in class_name else class_name
                )

                # 确保类型作用域存在
                if base_type_name not in self._type_scopes:
                    type_scope = TypeScope(base_type_name)
                    # 如果是模板类型，关联模板类型符号
                    if "[" in class_name:
                        template_symbol = self._template_types.get(base_type_name)
                        if template_symbol:
                            type_scope.template_symbol = template_symbol
                    self._type_scopes[base_type_name] = type_scope

                type_scope = self._type_scopes[base_type_name]

                # 根据是否为类方法，注册到不同的索引
                if signature.is_classmethod:
                    # 类方法：Class.method()
                    if func_name not in type_scope.class_methods:
                        type_scope.class_methods[func_name] = []
                    type_scope.class_methods[func_name].append(signature)
                else:
                    # 实例方法：obj.method()
                    if func_name not in type_scope.instance_methods:
                        type_scope.instance_methods[func_name] = []
                    type_scope.instance_methods[func_name].append(signature)
            return

        # === 处理全局函数 ===
        if func_name not in self._functions:
            self._functions[func_name] = Symbol(
                name=func_name,
                kind=SymbolKind.FUNCTION,
                priority=signature.priority,
            )
        self._functions[func_name].add_signature(signature)

    def register_type_config(self, type_name: str, config: Dict) -> None:
        """注册类型配置"""
        # 从全局类型查找并设置配置
        if type_name in self._types:
            self._types[type_name].type_config = config
        # 回退到旧系统类型
        elif type_name in self._primitive_types:
            self._primitive_types[type_name].type_config = config
        elif type_name in self._template_types:
            self._template_types[type_name].type_config = config

    def lookup_type_symbol(
        self, type_name: str, args_types: Optional[List[TypeInfo]] = None
    ) -> Optional[Symbol]:
        """查找类型符号，采用 C++ 风格的模板查找机制

        查找优先级：
        1. 类型别名解析
        2. 模板特化匹配（精确匹配）
        3. 模板实例化（从基础模板生成）
        4. 基础类型查找

        Args:
            type_name: 类型名称
            args_types: 泛型参数类型列表

        Returns:
            匹配的类型符号，如果找不到则返回 None
        """
        # 1. 解析别名
        canonical_name = self._type_aliases.get(type_name, type_name)

        # 2. 无参数 - 查找基础类型或模板类型
        if not args_types:
            # 先查基础类型
            if canonical_name in self._primitive_types:
                return self._primitive_types[canonical_name]
            # 再查模板类型
            if canonical_name in self._template_types:
                return self._template_types[canonical_name]
            # 回退到全局类型
            if canonical_name in self._types:
                return self._types[canonical_name]
            return None

        # 3. 有参数 - 构建签名并查找实例化类型
        temp_type_info = TypeInfo(
            kind=TypeKind.GENERIC, name=canonical_name, args=args_types
        )
        signature = build_type_signature(temp_type_info)

        # 检查缓存
        if signature in self._instantiated_types:
            return self._instantiated_types[signature]

        # 查找模板并实例化
        template = self._template_types.get(canonical_name)
        if template and self._validate_template_args(template, args_types):
            instance = self._instantiate_template(template, args_types, signature)
            if instance:
                self._instantiated_types[signature] = instance
                return instance

        return None

    def _validate_template_args(self, template: Symbol, args: List[TypeInfo]) -> bool:
        """验证模板参数"""
        template_info = template.type_info
        if not template_info:
            return False

        if template_info.is_variadic_template:
            # 可变参数模板验证
            return len(args) >= template_info.min_template_args and (
                template_info.max_template_args is None
                or len(args) <= template_info.max_template_args
            )
        else:
            # 固定参数模板验证
            return len(args) == len(template_info.template_params)

    def _instantiate_template(
        self, template: Symbol, args: List[TypeInfo], signature: str
    ) -> Symbol:
        """实例化模板"""
        from mcpy.symbol_meta import TypeInfo, TypeKind

        # 创建实例化的 TypeInfo
        instance_type_info = TypeInfo(
            kind=TypeKind.GENERIC,
            name=template.name,  # 使用模板基础名称（如 "list"），不是签名
            args=args,
            is_instantiated=True,
            template_base=template.name,
            instantiation_args=args,
        )

        # 创建实例化的 Symbol
        instance_symbol = Symbol(
            name=signature,
            kind=SymbolKind.CLASS,
            type_info=instance_type_info,
            type_config=self._build_instance_config(template, args),
        )

        return instance_symbol

    def _build_instance_config(self, template: Symbol, args: List[TypeInfo]) -> Dict:
        """构建实例化类型的配置"""
        if not template.type_config:
            return {}

        # 深拷贝配置，避免修改原始模板的配置
        import copy

        config = copy.deepcopy(template.type_config)

        # 处理 C++ 类型模板替换
        cpp_type = config.get("cpp_type", "")
        if cpp_type and template.type_info:
            # 替换模板参数
            if template.type_info.is_variadic_template:
                # 可变参数模板：先替换固定参数，再替换可变参数
                from mcpy.type_system import get_cpp_type

                # 获取模板参数列表
                template_params = template.type_info.template_params or []

                # 分离固定参数和可变参数
                fixed_param_count = template.type_info.min_template_args or 0
                fixed_params = template_params[:fixed_param_count]
                variadic_param = (
                    template_params[fixed_param_count]
                    if len(template_params) > fixed_param_count
                    else None
                )

                # 替换固定参数
                for i, param_name in enumerate(fixed_params):
                    if i < len(args):
                        arg_cpp_type = get_cpp_type(args[i], registry=self)
                        if arg_cpp_type:
                            cpp_type = cpp_type.replace(
                                f"{{{param_name}}}", arg_cpp_type
                            )

                # 替换可变参数
                if variadic_param:
                    if len(args) > fixed_param_count:
                        # 有可变参数
                        variadic_args = args[fixed_param_count:]
                        cpp_variadic_args = []
                        for arg in variadic_args:
                            arg_cpp_type = get_cpp_type(arg, registry=self)
                            if arg_cpp_type:
                                cpp_variadic_args.append(arg_cpp_type)

                        if cpp_variadic_args:
                            variadic_str = ", ".join(cpp_variadic_args)
                            # 替换 {Args}... 格式
                            cpp_type = cpp_type.replace(
                                f"{{{variadic_param}}}...", variadic_str
                            )
                            # 也支持 {Args...} 格式
                            cpp_type = cpp_type.replace(
                                f"{{{variadic_param}...}}", variadic_str
                            )
                        else:
                            # 没有可变参数，移除可变参数部分
                            cpp_type = cpp_type.replace(
                                f", {{{variadic_param}}}...", ""
                            )
                            cpp_type = cpp_type.replace(
                                f", {{{variadic_param}...}}", ""
                            )
                            cpp_type = cpp_type.replace(f"{{{variadic_param}}}...", "")
                            cpp_type = cpp_type.replace(f"{{{variadic_param}...}}", "")
                    else:
                        # 没有可变参数，移除可变参数部分
                        cpp_type = cpp_type.replace(f", {{{variadic_param}}}...", "")
                        cpp_type = cpp_type.replace(f", {{{variadic_param}...}}", "")
                        cpp_type = cpp_type.replace(f"{{{variadic_param}}}...", "")
                        cpp_type = cpp_type.replace(f"{{{variadic_param}...}}", "")
            else:
                # 固定参数模板：替换 {T}, {K}, {V} 等
                for i, param_name in enumerate(template.type_info.template_params):
                    if i < len(args):
                        from mcpy.type_system import get_cpp_type

                        # 检查参数是否本身就是模板参数（如 T, K, V）
                        # 如果 args[i].name 与某个模板参数同名，直接使用名称而不查找
                        if args[i].name in template.type_info.template_params:
                            # 这是一个模板参数（如 list[T] 中的 T），直接使用
                            arg_cpp_type = args[i].name
                        elif args[i].kind == TypeKind.TEMPLATE:
                            # TypeVar 声明的模板参数
                            arg_cpp_type = args[i].name
                        else:
                            # 普通类型，需要查找 C++ 映射
                            arg_cpp_type = get_cpp_type(args[i], registry=self)

                            # 如果查找失败，尝试直接使用类型名
                            # 这可能是一个 C++ 类型（如 mc::variant）而不是 Python 类型
                            if not arg_cpp_type and args[i].name:
                                arg_cpp_type = args[i].name

                        if arg_cpp_type:
                            cpp_type = cpp_type.replace(
                                f"{{{param_name}}}", arg_cpp_type
                            )

            config["cpp_type"] = cpp_type

        # 标记为泛型实例化类型
        config["is_generic_instance"] = True
        config["template_args"] = args
        config["base_type"] = template.name

        return config

    def _is_generic_type(self, symbol: Symbol) -> bool:
        """检查符号是否为泛型类型"""
        if not symbol.type_config:
            return False

        return (
            symbol.type_config.get("is_generic", False)
            or "template_params" in symbol.type_config
            or "generic_params" in symbol.type_config
            or "inherit_from" in symbol.type_config
            or "type_substitution" in symbol.type_config
        )

    def _validate_generic_constraints(
        self, base_symbol: Symbol, args_types: List[TypeInfo]
    ) -> bool:
        """验证泛型参数约束"""
        if not base_symbol.type_config:
            return False

        # 从 inherit_from 解析期望的参数数量
        inherit_from = base_symbol.type_config.get("inherit_from", "")
        if inherit_from and "[" in inherit_from and "]" in inherit_from:
            params_part = inherit_from[
                inherit_from.find("[") + 1 : inherit_from.find("]")
            ]
            if params_part.strip():
                expected_count = len([p.strip() for p in params_part.split(",")])
                return len(args_types) == expected_count

        # 启发式规则：根据配置的 inherit_from 推断参数数量
        # 或者从模板符号中获取期望的参数数量
        type_config = (
            base_symbol.type_config if hasattr(base_symbol, "type_config") else None
        )
        if type_config:
            inherit_from = type_config.get("inherit_from")
            if inherit_from and "[" in inherit_from and "]" in inherit_from:
                # 从 inherit_from 中解析参数数量
                # 例如："list[T]" -> 1, "dict[K, V]" -> 2
                params_part = inherit_from[
                    inherit_from.find("[") + 1 : inherit_from.find("]")
                ]
                if params_part.strip():
                    expected_count = len([p.strip() for p in params_part.split(",")])
                    return len(args_types) == expected_count

        # 回退：如果有模板参数信息，使用它
        if hasattr(base_symbol, "type_info") and base_symbol.type_info:
            template_params = getattr(base_symbol.type_info, "template_params", None)
            if template_params:
                return len(args_types) == len(template_params)

        return True  # 默认接受

    def _create_generic_instance_symbol(
        self, base_symbol: Symbol, type_name: str, args_types: List[TypeInfo]
    ) -> Symbol:
        """创建泛型实例符号"""
        from mcpy.type_system import _handle_generic_instantiation
        from mcpy.symbol_meta import TypeInfo, TypeKind

        # 构造完整的 TypeInfo
        type_info = TypeInfo(kind=TypeKind.GENERIC, name=type_name, args=args_types)
        return _handle_generic_instantiation(base_symbol, type_info)

    def get_type_config(self, type_name: str) -> Optional[Dict]:
        """获取类型配置"""
        # 从新系统查找
        symbol = self._types.get(type_name)
        if symbol and symbol.type_config:
            return symbol.type_config
        # 从类型系统查找
        symbol = self._primitive_types.get(type_name)
        if symbol and symbol.type_config:
            return symbol.type_config
        symbol = self._template_types.get(type_name)
        if symbol and symbol.type_config:
            return symbol.type_config
        return None

    def remove_function(self, function_name: str) -> None:
        """移除函数符号"""
        if function_name in self._functions:
            del self._functions[function_name]

    def remove_type_symbol(self, type_name: str) -> None:
        """移除类型符号"""
        if type_name in self._types:
            del self._types[type_name]
        if type_name in self._primitive_types:
            del self._primitive_types[type_name]
        if type_name in self._template_types:
            del self._template_types[type_name]

    def remove_symbol(self, symbol_name: str) -> None:
        """移除符号"""
        # 尝试从函数移除
        if symbol_name in self._functions:
            del self._functions[symbol_name]
            return
        # 尝试从类型移除
        if symbol_name in self._types:
            del self._types[symbol_name]
            return
        if symbol_name in self._primitive_types:
            del self._primitive_types[symbol_name]
            return
        if symbol_name in self._template_types:
            del self._template_types[symbol_name]
            return

    def list_type_symbols(self) -> List[str]:
        """列出所有类型符号名称"""
        types = set()
        # 从新系统收集
        types.update(self._types.keys())
        # 从类型系统收集
        types.update(self._primitive_types.keys())
        types.update(self._template_types.keys())
        return list(types)

    def list_functions(self) -> List[str]:
        """列出所有函数名称"""
        return list(self._functions.keys())

    def list_symbols(self) -> List[str]:
        """列出所有符号名称"""
        symbols = set()
        # 收集所有类型
        symbols.update(self._types.keys())
        symbols.update(self._primitive_types.keys())
        symbols.update(self._template_types.keys())
        # 收集所有函数
        symbols.update(self._functions.keys())
        # 收集所有类型的方法（可选，通常不需要）
        for type_scope in self._type_scopes.values():
            symbols.update(type_scope.instance_methods.keys())
            symbols.update(type_scope.class_methods.keys())
        return list(symbols)

    def find_best_match_with_typeinfo(
        self, function_name: str, arg_type_infos: Optional[List[TypeInfo]] = None
    ) -> Optional[Signature]:
        """查找最佳匹配的签名"""
        # 使用新接口查找全局函数
        symbol = self.lookup_global_function(function_name, arg_type_infos)

        if symbol:
            return symbol.find_matching_signature(arg_type_infos)

        return None

    def get_all_signatures(self, function_name: str) -> List[Signature]:
        """获取函数的所有签名"""
        symbol = self._functions.get(function_name)
        if symbol and symbol.signatures:
            return symbol.signatures
        return []

    def get_symbol(self, name: str) -> Optional[Symbol]:
        """获取符号（公共接口）

        优先从新系统查找。

        Args:
            name: 符号名称

        Returns:
            找到的符号，如果不存在则返回 None
        """
        # 先尝试从全局函数查找
        symbol = self._functions.get(name)
        if symbol:
            return symbol

        # 再尝试从全局类型查找
        symbol = self._types.get(name)
        if symbol:
            return symbol

        # 从类型系统查找
        symbol = self._primitive_types.get(name)
        if symbol:
            return symbol

        symbol = self._template_types.get(name)
        if symbol:
            return symbol

        return None

    def clear(self) -> None:
        """清空所有符号"""
        self._type_scopes.clear()
        self._functions.clear()
        self._types.clear()
        self._primitive_types.clear()
        self._template_types.clear()
        self._type_aliases.clear()
        self._instantiated_types.clear()

    def lookup_global_function(
        self, func_name: str, args_types: Optional[List[TypeInfo]] = None
    ) -> Optional[Symbol]:
        """查找全局函数

        Args:
            func_name: 函数名
            args_types: 参数类型列表（用于重载匹配）

        Returns:
            函数符号，如果找不到则返回 None
        """
        symbol = self._functions.get(func_name)
        if symbol and args_types:
            # 验证签名匹配
            if symbol.find_matching_signature(args_types):
                return symbol
            return None
        return symbol

    def lookup_instance_method(
        self,
        owner_type: str,
        method_name: str,
        args_types: Optional[List[TypeInfo]] = None,
    ) -> Optional[Symbol]:
        """查找实例方法：obj.method()

        Args:
            owner_type: 所属类型名（如 "dict", "list[int]"）
            method_name: 方法名
            args_types: 参数类型列表（不包含 self）

        Returns:
            方法符号，如果找不到则返回 None
        """
        return self._lookup_method_in_scope(
            owner_type, method_name, args_types, is_classmethod=False
        )

    def lookup_class_method(
        self,
        owner_type: str,
        method_name: str,
        args_types: Optional[List[TypeInfo]] = None,
    ) -> Optional[Symbol]:
        """查找类方法/静态方法：Class.method()

        Args:
            owner_type: 所属类型名（如 "dict", "list"）
            method_name: 方法名
            args_types: 参数类型列表（不包含 self）

        Returns:
            方法符号，如果找不到则返回 None
        """
        return self._lookup_method_in_scope(
            owner_type, method_name, args_types, is_classmethod=True
        )

    def _lookup_method_in_scope(
        self,
        owner_type: str,
        method_name: str,
        args_types: Optional[List[TypeInfo]],
        is_classmethod: bool,
    ) -> Optional[Symbol]:
        """在类型作用域中查找方法

        支持模板匹配：对于 tuple[int, int, int]，可以匹配到 tuple[T, Args...] 的方法
        使用模板类型符号的结构化信息进行匹配，而不是字符串解析。
        """
        from mcpy.type_system import parse_type_with_context

        # 提取基础类型名
        base_type_name = owner_type.split("[")[0] if "[" in owner_type else owner_type

        # 查找基础类型的 TypeScope
        type_scope = self._type_scopes.get(base_type_name)
        if not type_scope:
            return None

        # 获取模板类型符号（如果存在）
        template_symbol = self._template_types.get(base_type_name)

        # 解析 owner_type 获取类型参数信息
        owner_type_info = parse_type_with_context(owner_type, registry=self)
        owner_arg_count = (
            len(owner_type_info.args) if owner_type_info and owner_type_info.args else 0
        )

        # 根据方法类型选择正确的索引
        method_index = (
            type_scope.class_methods if is_classmethod else type_scope.instance_methods
        )

        # 获取所有方法签名
        all_signatures = method_index.get(method_name, [])

        if not all_signatures:
            return None

        # 如果 owner_type 是实例化类型且有模板符号，使用模板匹配
        if owner_arg_count > 0 and template_symbol and template_symbol.type_info:
            filtered_signatures = self._filter_matching_signatures_with_template(
                all_signatures,
                owner_type,
                owner_arg_count,
                base_type_name,
                template_symbol,
            )
        else:
            # 基础类型或无模板符号，直接过滤为基础类型签名
            filtered_signatures = self._filter_matching_signatures_for_base_type(
                all_signatures, owner_type, base_type_name
            )

        # 查找最佳匹配的签名
        matching_sig = None
        if args_types:
            best_score = 0
            for signature in filtered_signatures:
                # 使用签名匹配算法
                score = signature.matches_call_with_typeinfo(method_name, args_types)
                if score > best_score:
                    best_score = score
                    matching_sig = signature

        # 如果没有找到匹配的，或者没有提供参数类型，从过滤后的签名中选择最优先的
        if not matching_sig:
            matching_sig = filtered_signatures[0] if filtered_signatures else None

        if matching_sig:
            return self._build_method_symbol(
                method_name, matching_sig, filtered_signatures, owner_type
            )

        return None

    def _is_template_type_match(
        self, template_symbol: "Symbol", owner_arg_count: int
    ) -> bool:
        """使用模板类型符号的结构化信息判断是否匹配

        Args:
            template_symbol: 模板类型符号（如 tuple[T, Args...] 的符号）
            owner_arg_count: owner_type 的类型参数数量（如 tuple[int, int, int] 是 3）

        Returns:
            是否匹配
        """
        if not template_symbol or not template_symbol.type_info:
            return False

        type_info = template_symbol.type_info

        # 如果是可变参数模板
        if type_info.is_variadic_template:
            # 检查参数数量是否满足最小值要求
            return owner_arg_count >= type_info.min_template_args

        # 固定参数模板：参数数量必须完全匹配
        expected_count = len(type_info.template_params)
        return owner_arg_count == expected_count

    def _filter_matching_signatures_with_template(
        self,
        signatures: List[Signature],
        owner_type: str,
        owner_arg_count: int,
        base_type_name: str,
        template_symbol: "Symbol",
    ) -> List[Signature]:
        """使用模板类型符号的结构化信息过滤匹配的签名

        优先级：
        1. 模板匹配（如 tuple[T, Args...] 匹配 tuple[int, int, int]）- 使用结构化信息
        2. 基础类型匹配（如 tuple 匹配 tuple[int, int, int]）

        使用 Signature 中的结构化信息（variadic_param_index、min_template_args 等）
        而不是字符串解析。
        """
        template_matches = []
        base_matches = []

        for sig in signatures:
            if not sig.param_types or len(sig.param_types) == 0:
                continue

            sig_owner_type = sig.param_types[0]

            # 情况1：模板类型签名（如 tuple[T, Args...]）
            # 优先使用 Signature 中的结构化信息
            if sig.template_params_detailed:
                # 使用结构化的模板参数信息
                sig_base = (
                    sig_owner_type.split("[")[0]
                    if "[" in sig_owner_type
                    else sig_owner_type
                )
                if sig_base == base_type_name:
                    # 使用 Signature 中的可变参数信息判断是否匹配
                    if self._is_signature_template_match(sig, owner_arg_count):
                        template_matches.append(sig)
            # 回退：使用字符串解析（向后兼容）
            elif "[" in sig_owner_type:
                # 检查签名的基础类型是否匹配
                sig_base = sig_owner_type.split("[")[0]
                if sig_base == base_type_name:
                    # 使用模板符号的结构化信息判断是否匹配
                    if self._is_template_type_match(template_symbol, owner_arg_count):
                        template_matches.append(sig)
            # 情况2：基础类型签名（如 tuple）
            elif sig_owner_type == base_type_name:
                base_matches.append(sig)

        # 按优先级返回：模板匹配 > 基础类型匹配
        if template_matches:
            return template_matches
        else:
            return base_matches

    def _is_signature_template_match(
        self, signature: "Signature", owner_arg_count: int
    ) -> bool:
        """使用 Signature 中的结构化信息判断模板匹配

        Args:
            signature: 方法签名
            owner_arg_count: owner_type 的类型参数数量（如 tuple[int, int, int] 是 3）

        Returns:
            是否匹配

        使用 Signature 中的 variadic_param_index、min_template_args、max_template_args
        而不是字符串解析。
        """
        if not signature.template_params_detailed:
            return False

        # 如果有可变参数信息，使用结构化信息
        if signature.variadic_param_index is not None:
            # 有可变参数：检查参数数量是否满足最小值要求
            return owner_arg_count >= signature.min_template_args

        # 无可变参数：参数数量必须完全匹配
        expected_count = len(signature.template_params_detailed)
        return owner_arg_count == expected_count

    def _filter_matching_signatures_for_base_type(
        self, signatures: List[Signature], owner_type: str, base_type_name: str
    ) -> List[Signature]:
        """为基础类型过滤匹配的签名

        返回基础类型的签名（如 tuple 的方法）
        也匹配模板类型的签名（如 tuple[T, Args...]）用于基础类型
        """
        base_matches = []

        for sig in signatures:
            if not sig.param_types or len(sig.param_types) == 0:
                continue

            sig_owner_type = sig.param_types[0]

            # 匹配基础类型签名（如 "dict"）
            if sig_owner_type == base_type_name:
                base_matches.append(sig)
            # 对于类方法，也匹配模板类型签名（如 "dict[K, V]"）用于基础类型（如 "dict"）
            elif "[" in sig_owner_type:
                sig_base = sig_owner_type.split("[")[0]
                if sig_base == base_type_name:
                    base_matches.append(sig)

        return base_matches

    def _extract_type_args_from_owner_type(
        self, owner_type: str
    ) -> Dict[str, "TypeInfo"]:
        """从 owner_type 提取类型参数映射

        例如：
        - "list[Any]" -> {"T": TypeInfo(Any)}
        - "dict[str, int]" -> {"K": TypeInfo(str), "V": TypeInfo(int)}
        - "list" -> {}

        使用模板类型符号中存储的 template_params，而不是硬编码。
        """
        from .type_system import parse_type_with_context

        # 解析 owner_type 字符串为 TypeInfo
        # 使用 registry=self 以正确识别 TypeVar
        try:
            owner_type_info = parse_type_with_context(owner_type, registry=self)
        except:
            return {}

        # 如果没有类型参数，返回空映射
        if not owner_type_info.args:
            return {}

        # 查找基础类型的模板符号，获取模板参数名称
        base_type = owner_type_info.name
        template_symbol = self._template_types.get(base_type)

        if not template_symbol or not template_symbol.type_info:
            # 如果找不到模板符号，回退到默认行为
            # 使用 T, T1, T2, ... 作为参数名
            template_param_names = [
                f"T{i}" if i > 0 else "T" for i in range(len(owner_type_info.args))
            ]
        else:
            # 从模板符号获取模板参数名称
            template_param_names = template_symbol.type_info.template_params

            # 如果模板参数数量不匹配，回退到默认行为
            if len(template_param_names) != len(owner_type_info.args):
                template_param_names = [
                    f"T{i}" if i > 0 else "T" for i in range(len(owner_type_info.args))
                ]

        # 构建映射
        type_arg_map = {}
        for param_name, type_arg in zip(template_param_names, owner_type_info.args):
            type_arg_map[param_name] = type_arg

        return type_arg_map

    def _substitute_template_params(
        self, type_info: Optional["TypeInfo"], type_arg_map: Dict[str, "TypeInfo"]
    ) -> Optional["TypeInfo"]:
        """递归替换 TypeInfo 中的模板参数

        例如：
        - type_info=TypeInfo(name="T"), type_arg_map={"T": TypeInfo(Any)} -> TypeInfo(Any)
        - type_info=TypeInfo(name="list", args=[TypeInfo(name="T")]), type_arg_map={"T": TypeInfo(Any)} -> TypeInfo(name="list", args=[TypeInfo(Any)])
        """
        from .type_system import TypeInfo, TypeKind

        if not type_info:
            return type_info

        # 如果是模板参数（名称在映射中），直接替换
        if type_info.name in type_arg_map:
            return type_arg_map[type_info.name]

        # 如果有类型参数，递归替换
        if type_info.args:
            new_args = [
                self._substitute_template_params(arg, type_arg_map) or TypeInfo.any()
                for arg in type_info.args
            ]
            # 创建新的 TypeInfo，保持其他属性不变
            return TypeInfo(
                kind=type_info.kind,
                name=type_info.name,
                args=new_args,
                return_type=(
                    self._substitute_template_params(
                        type_info.return_type, type_arg_map
                    )
                    if type_info.return_type
                    else None
                ),
                module=type_info.module,
                attributes=type_info.attributes,
            )

        # 否则返回原 TypeInfo
        return type_info

    def _build_method_symbol(
        self,
        method_name: str,
        matching_sig: Signature,
        all_signatures: List[Signature],
        owner_type: str,
    ) -> Symbol:
        """从签名构建方法符号（内部辅助方法）

        会根据 owner_type 进行模板参数替换。
        例如：owner_type="list[Any]" 时，会将签名中的 T 替换为 Any
        """
        from .type_system import (
            parse_type_string_with_template_context,
            TypeInfo,
            TypeKind,
        )

        # 获取签名的模板参数列表
        template_params = matching_sig.template_params or []

        # 解析 owner_type 以提取类型参数（如 list[Any] -> {"T": TypeInfo(Any)}）
        type_arg_map = self._extract_type_args_from_owner_type(owner_type)

        # 解析返回类型（使用模板上下文）
        return_type = None
        if matching_sig.return_type:
            return_type = parse_type_string_with_template_context(
                matching_sig.return_type, template_params
            )
            # 替换模板参数
            return_type = self._substitute_template_params(return_type, type_arg_map)

        # 解析参数类型（使用模板上下文）
        param_type_infos = []
        for param_type_str in matching_sig.param_types:
            param_type = parse_type_string_with_template_context(
                param_type_str, template_params
            )
            # 替换模板参数
            param_type = self._substitute_template_params(param_type, type_arg_map)
            param_type_infos.append(param_type)

        # 创建方法类型信息
        method_type = TypeInfo(
            kind=TypeKind.FUNCTION,
            name=method_name,
            args=param_type_infos,
            return_type=return_type,
            module="builtins",
        )

        symbol = Symbol(
            name=method_name,
            kind=SymbolKind.METHOD,
            type_info=method_type,
            module=(matching_sig.includes[0] if matching_sig.includes else None),
        )
        # 添加所有签名，而不仅仅是匹配的那一个
        # 这样在代码生成阶段可以重新匹配正确的签名
        for sig in all_signatures:
            symbol.add_signature(sig)
        return symbol

    def lookup_type_symbol_new(self, type_name: str) -> Optional[Symbol]:
        """查找类型符号（新接口）

        Args:
            type_name: 类型名

        Returns:
            类型符号，如果找不到则返回 None
        """
        return self._types.get(type_name)


# 全局注册表实例
global_registry = None
_global_registry_initializing = False  # 初始化标志，防止递归


def get_global_registry() -> SymbolRegistry:
    """获取全局注册表"""
    global global_registry, _global_registry_initializing
    if not global_registry:
        _global_registry_initializing = True  # 设置初始化标志
        try:
            global_registry = SymbolRegistry()
            _initialize_builtin_symbols(global_registry)
        finally:
            _global_registry_initializing = False  # 清除初始化标志

    return global_registry


def is_global_registry_initializing() -> bool:
    """检查全局 registry 是否正在初始化"""
    return _global_registry_initializing


def _initialize_builtin_symbols(registry: SymbolRegistry) -> None:
    """初始化内置符号

    局部导入原因：
    1. 避免循环依赖：type_system 和 builtin_table 都依赖 symbol_registry
    2. 延迟加载：这是全局单例的初始化函数，不频繁调用
    3. 可选依赖：builtin_table 可能不存在（ImportError）
    """
    # 使用 type_system 中的统一初始化函数
    from .type_system import initialize_builtin_types_to_registry

    initialize_builtin_types_to_registry(registry)

    # 注册 builtin TypeVars
    from .builtin.builtin_table import GLOBAL_TEMPLATE_PARAMS

    for name, template_param in GLOBAL_TEMPLATE_PARAMS.items():
        # 创建 TypeVar 符号（类型参数，不是普通变量）
        # 约束信息存储在 template_param 中，无需额外注册
        typevar_symbol = Symbol(
            name=name,
            kind=SymbolKind.TYPE_PARAM,  # 类型参数（不是 VARIABLE）
            type_info=TypeInfo(kind=TypeKind.TYPE_PARAM, name=name),  # 类型参数类型
            template_params=[template_param],  # 存储约束信息
            module="builtins",  # 全局作用域
        )

        # 注册到全局类型表（作为全局可访问的符号）
        registry._types[name] = typevar_symbol

    # 注册内置函数
    from .builtin.builtin_table import load_builtin_signatures

    try:
        for signature in load_builtin_signatures():
            registry.register_signature(signature)
    except ImportError:
        pass
